﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Billing.Controls;
using Billing.Dtos;
using Billing.Utilities;

namespace Billing.Windows
{
    public partial class BillingGrid : Window
    {
        int billingScreensCount;
        internal string payCash = string.Empty;
        internal string paySodexo = string.Empty;
        internal string payCard = string.Empty;
        internal double cashAmount = 0;
        internal double sodexoAmount = 0;
        internal double cardAmount = 0;
        public Dictionary<string, string> payType = new Dictionary<string, string>();
        bool m_FromCreditNote = false;
        double screenHeight = 0;
        List<LessStockItemsDto> m_LessStockItems = new List<LessStockItemsDto>();

        public bool IsExit { get; set; }
        public int BillNo { get; set; }
        public List<string> ExtraItems = null;

        #region constructor

        public BillingGrid()
        {
            try
            {
                InitializeComponent();

                //Mouse.OverrideCursor = Cursors.None;

                DispatcherTimer timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
                {
                    this.dateText.Text = DateTime.Now.ToString("dd/MMM/yyyy   hh:mm:ss tt") + "         " + Storage.CreditNoteCompany;
                }, this.Dispatcher);

                //DispatcherTimer timerCheckConnectivity = new DispatcherTimer(new TimeSpan(0, 0, 30), DispatcherPriority.Normal, delegate
                //{
                //    CheckConnectivity();
                //}, this.Dispatcher);

                //CheckConnectivity();
                try
                {
                    ExtraItems = ConfigurationManager.AppSettings.GetValues("ExtraBillItems")[0].Split(',').ToList();
                }
                catch (Exception) { }
                ReadItems();
                ltMainList.Items.Add(new BillingGridItemControl(this));
                ltMainList.Focus();
                BillingGridItemControl firstItem = (BillingGridItemControl)ltMainList.SelectedItem;
                ltMainList.SelectedIndex = 0;
                UpdateBillItemsSlNo();
                screenHeight = this.Height;
                ltMainList.Height = screenHeight / 1.7;

                BillNo = Database.GetNextBillNo();
                //rBillNo.Text = ConfigurationManager.AppSettings["BranchLetter"] + BillNo;
                rBillNo.Text = Database.BranchLetter + BillNo;

                foreach (BillingGridItemDto item in CacheManager.BillingItems.OrderBy(i => i.Code).ToList())
                {
                    if (item.IsStockShown)
                        ltLessStockDetails.Items.Add(item);
                }

                SetDefaults();
                Storage.IsFirstBill = false;
            }
            catch (Exception) { }
        }

        //private void CheckConnectivity()
        //{
        //    var ping = new Ping();
        //    var options = new PingOptions { DontFragment = true };

        //    //just need some data. this sends 10 bytes. 
        //    var buffer = Encoding.ASCII.GetBytes(new string('z', 10));
        //    PingReply reply = null;
        //    try
        //    {
        //        reply = ping.Send(ConfigurationManager.AppSettings["MachineToPing"], 60, buffer, options);
        //    }
        //    catch (Exception)
        //    {
        //        reply = null;
        //    }

        //    if (reply != null && reply.Status == IPStatus.Success)
        //    {
        //        success.Visibility = Visibility.Visible;
        //        failure.Visibility = Visibility.Hidden;
        //    }
        //    else
        //    {
        //        success.Visibility = Visibility.Hidden;
        //        failure.Visibility = Visibility.Visible;
        //    }
        //}

        public BillingGrid(int billCount) : this()
        {
            billingScreensCount = billCount + 1;
            rBillNo.Text = billingScreensCount.ToString();
        }

        public BillingGrid(bool fromCreditNote) : this()
        {
            m_FromCreditNote = fromCreditNote;
        }

        #endregion

        #region events

        private void ltMainList_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                BillingGridItemControl currentItem = GetCurrentGridItem();
                if (currentItem == null)
                    currentItem = GetBillingGridLastItem();

                if (e.Key == Key.Up)
                {
                    ltMainList.SelectedIndex = ltMainList.SelectedIndex > 0 ? ltMainList.SelectedIndex - 1 : 0;
                    BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                    item.txtQty.Focus();
                    item.txtQty.SelectAll();
                }
                else if (e.Key == Key.Down)
                {
                    ltMainList.SelectedIndex = ltMainList.SelectedIndex + 1;
                    BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                    item.txtQty.Focus();
                    item.txtQty.SelectAll();
                }
                else if (e.Key == Key.Left || (e.Key == Key.Enter && currentItem.txtQty.IsFocused && currentItem.txtCode.Text == string.Empty))
                {
                    BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                    if (item.txtQty.IsFocused)
                    {
                        item.txtCode.Focus();
                        item.txtCode.SelectAll();
                    }
                }
                else if (e.Key == Key.Right)
                {
                    BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                    if (item.txtCode.IsFocused)
                    {
                        item.txtQty.Focus();
                        item.txtQty.SelectAll();
                    }
                }
                else if (e.Key == Key.Delete)
                {
                    if (ltMainList.Items.Count != 0)
                    {
                        try
                        {
                            int selectedIndex = ltMainList.SelectedIndex;
                            (ltMainList.Items[selectedIndex] as BillingGridItemControl).txtCode.Text = string.Empty;
                            (ltMainList.Items[selectedIndex] as BillingGridItemControl).txtQty.Text = "1";

                            ltMainList.SelectedIndex = selectedIndex;
                            if (ltMainList.SelectedItem == null)
                            {
                                FocusOnLastItem();
                                GetBillingGridLastItem().txtCode.Focus();
                            }
                            else
                            {
                                BillingGridItemControl item = GetCurrentGridItem();
                                item.txtCode.Focus();
                            }
                            UpdateBillItemsSlNo();
                            UpdateTotalCost();
                            UpdateTotalQty();
                        }
                        catch (Exception) { }
                    }
                }
                else if (currentItem.txtCode.Text == string.Empty && e.Key == Key.Enter && ltMainList.Items.Count > 1 && currentItem.txtCode.IsFocused && Storage.CanPrint && Storage.CanPrintForQtyModified)
                {
                    RefreshAllFields();
                    if (TotalAmount > 0.0M)
                    {
                        new Confirm().ShowDialog();

                        if (Storage.IsValid)
                        {
                            bool isItemsRemoved = false;
                            for (int i = 0; i < ltMainList.Items.Count; i++)
                            {
                                BillingGridItemControl item = ltMainList.Items[i] as BillingGridItemControl;
                                if (item.txtQty.Text == "0" || item.txtQty.Text == string.Empty || item.txtCode.Text == string.Empty)
                                {
                                    ltMainList.Items.Remove(ltMainList.Items[i]);
                                    isItemsRemoved = true;
                                    i -= 1;
                                }
                            }
                            if (isItemsRemoved)
                                UpdateBillItemsSlNo();

                            //Multi Bill Split Logic
                            PrintCommon.list1.Clear();
                            PrintCommon.list2.Clear();
                            PrintCommon.list3.Clear();
                            PrintCommon.list4.Clear();
                            PrintCommon.list5.Clear();

                            PrintCommon.list1Total = PrintCommon.list1Discount = 0;
                            PrintCommon.list2Total = PrintCommon.list2Discount = 0;
                            PrintCommon.list3Total = PrintCommon.list3Discount = 0;
                            PrintCommon.list4Total = PrintCommon.list4Discount = 0;
                            PrintCommon.list5Total = PrintCommon.list4Discount = 0;

                            foreach (BillingGridItemControl ctrl in ltMainList.Items)
                            {
                                if (ctrl.grp.Text == "1")
                                {
                                    PrintCommon.list1.Add(ctrl);
                                    PrintCommon.list1Total += double.Parse(ctrl.txtPrice.Text);
                                }
                                else if (ctrl.grp.Text == "2")
                                {
                                    PrintCommon.list2.Add(ctrl);
                                    PrintCommon.list2Total += double.Parse(ctrl.txtPrice.Text);
                                }
                                else if (ctrl.grp.Text == "3")
                                {
                                    PrintCommon.list3.Add(ctrl);
                                    PrintCommon.list3Total += double.Parse(ctrl.txtPrice.Text);
                                }
                                else if (ctrl.grp.Text == "4")
                                {
                                    PrintCommon.list4.Add(ctrl);
                                    PrintCommon.list4Total += double.Parse(ctrl.txtPrice.Text);
                                }
                                else if (ctrl.grp.Text == "5")
                                {
                                    PrintCommon.list5.Add(ctrl);
                                    PrintCommon.list5Total += double.Parse(ctrl.txtPrice.Text);
                                }
                            }

                            if (DiscountInRs != 0.0M)
                            {
                                double discount = Convert.ToDouble(DiscountInRs);

                                if (PrintCommon.list1Total < discount && PrintCommon.list2Total < discount && PrintCommon.list3Total < discount && PrintCommon.list4Total < discount)
                                {
                                    MessageBox.Show("Invalid Discount. Please enter in Individual Bills.", "Invalid Discount", MessageBoxButton.OK, MessageBoxImage.Error);
                                    ltMainList.SelectedIndex = ltMainList.Items.Count - 1;
                                    ((BillingGridItemControl)(ltMainList.Items[ltMainList.SelectedIndex])).txtCode.Focus();
                                    return;
                                }
                                else if (PrintCommon.list1Total >= discount)
                                {
                                    PrintCommon.list1Discount = discount;
                                }
                                else if (PrintCommon.list2Total >= discount)
                                {
                                    PrintCommon.list2Discount = discount;
                                }
                                else if (PrintCommon.list3Total >= discount)
                                {
                                    PrintCommon.list3Discount = discount;
                                }
                                else if (PrintCommon.list4Total >= discount)
                                {
                                    PrintCommon.list4Discount = discount;
                                }
                                else if (PrintCommon.list5Total >= discount)
                                {
                                    PrintCommon.list5Discount = discount;
                                }
                            }

                            //Setting Tokens whether required or not
                            //PrintCommon.list1Token = PrintCommon.list1.Exists(item => bool.Parse(item.slip.Text) == true);
                            //PrintCommon.list1Token = PrintCommon.list1.Exists(item => bool.Parse(item.slip.Text) == true);
                            //PrintCommon.list1Token = PrintCommon.list1.Exists(item => bool.Parse(item.slip.Text) == true);
                            //PrintCommon.list1Token = PrintCommon.list1.Exists(item => bool.Parse(item.slip.Text) == true);

                            if (ltMainList.Items.Count > 0)
                            {
                                string billNo = Database.GenerateBill(ltMainList.Items, rBillNo.Text, Double.Parse(DiscountInPercentage.ToString()), Double.Parse(DiscountInRs.ToString()), Double.Parse(TotalAmount.ToString()),
                                    Double.Parse(TotalNetAmount.ToString()), Double.Parse(PaytypeCashAmount.ToString()), Double.Parse(PaytypeSodexoAmount.ToString()), Double.Parse(PaytypeCardAmount.ToString()), DiscountReason);

                                Storage.BillNo = billNo;
                                Storage.PayableAmt = TotalNetAmount.ToString();
                                Storage.TotalAmount = TotalAmount.ToString();

                                Storage.DiscountByPercentage = null;
                                Storage.DiscountByRs = null;

                                if (DiscountInPercentage != 0.0M)
                                {
                                    Storage.DiscountByPercentage = DiscountInPercentage.ToString();
                                }

                                if (DiscountInRs != 0.0M)
                                {
                                    Storage.DiscountByRs = DiscountInRs.ToString();
                                }

                                Storage.DiscountedAmt = (TotalAmount - TotalNetAmount).ToString();

                                Storage.CashAmt = Double.Parse(PaytypeCashAmount.ToString());
                                Storage.CardAmt = Double.Parse(PaytypeCardAmount.ToString());
                                Storage.SodexhoAmt = Double.Parse(PaytypeSodexoAmount.ToString());
                                Storage.CreditNoteCompany = string.Empty;

                                if (billNo != string.Empty)
                                {
                                    try
                                    {
                                        /*PrintCommon.list1.Clear();
                                        PrintCommon.list2.Clear();
                                        PrintCommon.list3.Clear();
                                        PrintCommon.list4.Clear();

                                        PrintCommon.list1Total = 0;
                                        PrintCommon.list2Total = 0;
                                        PrintCommon.list3Total = 0;
                                        PrintCommon.list4Total = 0;

                                        foreach (BillingGridItemControl ctrl in ltMainList.Items)
                                        {
                                            if (ctrl.grp.Text == "1")
                                            {
                                                PrintCommon.list1.Add(ctrl);
                                                PrintCommon.list1Total += double.Parse(ctrl.txtPrice.Text);
                                            }
                                            else if (ctrl.grp.Text == "2")
                                            {
                                                PrintCommon.list2.Add(ctrl);
                                                PrintCommon.list2Total += double.Parse(ctrl.txtPrice.Text);
                                            }
                                            else if (ctrl.grp.Text == "3")
                                            {
                                                PrintCommon.list3.Add(ctrl);
                                                PrintCommon.list3Total += double.Parse(ctrl.txtPrice.Text);
                                            }
                                            else if (ctrl.grp.Text == "4")
                                            {
                                                PrintCommon.list4.Add(ctrl);
                                                PrintCommon.list4Total += double.Parse(ctrl.txtPrice.Text);
                                            }
                                        }*/

                                        if (PrintCommon.CreditNoteItems != null)
                                            PrintCommon.CreditNoteItems.Clear();
                                        if (PrintCommon.BulkOrderItems != null)
                                            PrintCommon.BulkOrderItems.Clear();
                                        if (PrintCommon.VendorItems != null)
                                            PrintCommon.VendorItems.Clear();

                                        int token = 0;

                                        foreach (BillingGridItemControl ctrl in ltMainList.Items)
                                        {
                                            if (bool.Parse(ctrl.slip.Text))
                                            {
                                                token = Database.GetToken();
                                                break;
                                            }
                                        }

                                        for (int i = 1; i < 6; i++)
                                        {
                                            try
                                            {
                                                if (i == 1)
                                                {
                                                    if (PrintCommon.list1.Count == 0)
                                                        continue;
                                                    PrintCommon.PrintItems = PrintCommon.list1;
                                                    PrintCommon.TotalAmt = PrintCommon.list1Total;
                                                    PrintCommon.Discount = PrintCommon.list1Discount;
                                                    PrintCommon.IsTokenRequired = PrintCommon.list1.Exists(item => bool.Parse(item.slip.Text) == true);
                                                    PrintCommon.Token = token.ToString();
                                                }
                                                else if (i == 2)
                                                {
                                                    if (PrintCommon.list2.Count == 0)
                                                        continue;
                                                    PrintCommon.PrintItems = PrintCommon.list2;
                                                    PrintCommon.TotalAmt = PrintCommon.list2Total;
                                                    PrintCommon.Discount = PrintCommon.list2Discount;
                                                    PrintCommon.IsTokenRequired = PrintCommon.list2.Exists(item => bool.Parse(item.slip.Text) == true);
                                                    PrintCommon.Token = token.ToString();
                                                }
                                                else if (i == 3)
                                                {
                                                    if (PrintCommon.list3.Count == 0)
                                                        continue;
                                                    PrintCommon.PrintItems = PrintCommon.list3;
                                                    PrintCommon.TotalAmt = PrintCommon.list3Total;
                                                    PrintCommon.Discount = PrintCommon.list3Discount;
                                                    PrintCommon.IsTokenRequired = PrintCommon.list3.Exists(item => bool.Parse(item.slip.Text) == true);
                                                    PrintCommon.Token = token.ToString();
                                                }
                                                else if (i == 4)
                                                {
                                                    if (PrintCommon.list4.Count == 0)
                                                        continue;
                                                    PrintCommon.PrintItems = PrintCommon.list4;
                                                    PrintCommon.TotalAmt = PrintCommon.list4Total;
                                                    PrintCommon.Discount = PrintCommon.list4Discount;
                                                    PrintCommon.IsTokenRequired = PrintCommon.list4.Exists(item => bool.Parse(item.slip.Text) == true);
                                                    PrintCommon.Token = token.ToString();
                                                }
                                                else if (i == 5)
                                                {
                                                    if (PrintCommon.list5.Count == 0)
                                                        continue;
                                                    PrintCommon.PrintItems = PrintCommon.list5;
                                                    PrintCommon.TotalAmt = PrintCommon.list5Total;
                                                    PrintCommon.Discount = PrintCommon.list5Discount;
                                                    PrintCommon.IsTokenRequired = PrintCommon.list5.Exists(item => bool.Parse(item.slip.Text) == true);
                                                    PrintCommon.Token = token.ToString();
                                                }

                                                if (ConfigurationManager.AppSettings["PrinterType"] != null && ConfigurationManager.AppSettings["PrinterType"].ToString() == "new")
                                                {
                                                    NewPrinter form = new NewPrinter();
                                                    form.printDocument1.PrintController = new StandardPrintController();
                                                    form.printDocument1.Print();
                                                }
                                                else
                                                {
                                                    Form1 form = new Form1();
                                                    form.printDocument1.PrintController = new StandardPrintController();
                                                    form.printDocument1.Print();
                                                }

                                                if (PrintCommon.PrintItems.Exists(item => bool.Parse(item.slip.Text) == true))
                                                {
                                                    TokenPrinter printer = new TokenPrinter(billNo, token);
                                                    printer.printDocument1.PrintController = new StandardPrintController();
                                                    printer.printDocument1.Print();
                                                }

                                                if (ExtraItems != null && ExtraItems.Count() > 0)
                                                {
                                                    foreach (BillingGridItemControl itemCtrl in PrintCommon.PrintItems)
                                                    {
                                                        if (ExtraItems.Contains(itemCtrl.txtCode.Text))
                                                        {
                                                            CouponPrinter printer = new CouponPrinter(billNo, itemCtrl.txtDesc.Text, itemCtrl.txtQty.Text);
                                                            printer.printDocument1.PrintController = new StandardPrintController();
                                                            printer.printDocument1.Print();
                                                        }
                                                    }
                                                }
                                            }
                                            catch (Exception) { }
                                        }
                                    }
                                    catch (Exception) { }
                                }

                                CacheManager.ResetCacheManager();
                                ltLessStockDetails.Items.Clear();
                                foreach (BillingGridItemDto item in CacheManager.BillingItems.OrderBy(i => i.Code).ToList())
                                {
                                    if (item.IsStockShown)
                                        ltLessStockDetails.Items.Add(item);
                                }
                                this.Close();

                                if (m_FromCreditNote)
                                    this.Close();
                            }
                            else
                            {
                                ltMainList.Items.Add(new BillingGridItemControl(this));
                            }
                        }
                    }
                }
                Storage.CanPrintForQtyModified = true;
            }
            catch (Exception) { }
        }

        private void ltMainList_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                BillingGridItemControl item = GetCurrentGridItem();
                if (item == null)
                {
                    if (ltMainList.Items.Count == 0)
                        ltMainList.Items.Add(new BillingGridItemControl(this));
                    item = GetBillingGridLastItem();
                }
                if (item.txtCode.Text != string.Empty && e.Key == Key.Enter)
                {
                    if (item != null && item.txtCode.IsFocused)
                    {
                        if (item.txtCode.Text.Trim() != string.Empty && IsCodeExist(Convert.ToInt32(item.txtCode.Text.Trim())))
                        {
                            item.txtQty.Focus();
                            item.txtQty.SelectAll();
                        }
                    }
                    else if (item == null || item.txtQty.IsFocused)
                    {
                        if (GetBillingGridLastItem().txtCode.Text.ToString().Trim() != string.Empty && GetBillingGridLastItem().txtQty.Text.ToString().Trim() != string.Empty)
                        {
                            BillingGridItemDto bItem = CacheManager.BillingItems.Find(it => it.Code.ToString() == GetBillingGridLastItem().txtCode.Text.ToString().Trim());
                            if (!bItem.AcceptNegativeStock && bItem.Stock < Convert.ToDouble(GetBillingGridLastItem().txtQty.Text.ToString().Trim()))
                            {
                                MessageBox.Show("Stock Not Available", "Invalid Stock", MessageBoxButton.OK, MessageBoxImage.Warning);
                                ((BillingGridItemControl)(ltMainList.Items[ltMainList.SelectedIndex])).txtCode.Text = string.Empty;
                                ((BillingGridItemControl)(ltMainList.Items[ltMainList.SelectedIndex])).txtQty.Text = string.Empty;
                                ((BillingGridItemControl)(ltMainList.Items[ltMainList.SelectedIndex])).txtCode.Focus();
                            }
                            else
                            {
                                ltMainList.Items.Add(new BillingGridItemControl(this));
                                ltMainList.SelectedIndex = ltMainList.SelectedIndex + 1;
                            }
                        }
                        GetBillingGridLastItem().txtCode.Focus();
                        FixRepeatedItems();
                        if (ltMainList.SelectedIndex == ltMainList.Items.Count - 1)
                            Storage.CanPrintForQtyModified = true;
                        else
                            Storage.CanPrintForQtyModified = false;
                        FocusOnLastItem();
                        UpdateBillItemsSlNo();
                    }
                    if (ltMainList.Items.Count <= 0)
                    {
                        ltMainList.Items.Add(new BillingGridItemControl(this));
                        FocusOnLastItem();
                    }
                }
                else if (e.Key == Key.Escape)
                {
                    if (MessageBox.Show("Do you want to discard this bill?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                    {
                        this.IsExit = true;
                        this.Close();
                    }
                }
                else if (e.Key == Key.F1)
                {
                    Stock help = new Stock(WindowTypes.BillingWindowF1);
                    help.Owner = this;
                    help.ShowDialog();
                    item.txtCode.Text = help.code;
                    item.txtDesc.Text = help.desc;
                }
                else if (e.Key == Key.F2 || e.Key == Key.F3)
                {
                    RefreshAllFields();
                    Discount discount = new Discount(this, (e.Key == Key.F3));
                    discount.Owner = this;
                    discount.ShowDialog();
                    CalculateNetTotal();
                }
                //else if (e.Key == Key.F4)
                //{
                //    PayType payType = new PayType(this);
                //    payType.Owner = this;
                //    payType.ShowDialog();
                //}
                else if (e.Key == Key.F5)
                {
                    CancelBill cancelBill = new CancelBill();
                    cancelBill.Owner = this;
                    cancelBill.ShowDialog();
                    CacheManager.ResetCacheManager();
                    ltLessStockDetails.Items.Clear();
                    foreach (BillingGridItemDto itemBG in CacheManager.BillingItems.OrderBy(i => i.Code).ToList())
                    {
                        if (itemBG.IsStockShown)
                            ltLessStockDetails.Items.Add(itemBG);
                    }
                }
                else if (e.Key == Key.F6)
                {
                    CakeBooking cakeBooking = new CakeBooking();
                    cakeBooking.Owner = this;
                    cakeBooking.ShowDialog();
                }
                else if (e.Key == Key.F7)
                {
                    BillingGrid secondBillingScreen = new BillingGrid(billingScreensCount);
                    secondBillingScreen.Owner = this;
                    secondBillingScreen.ShowDialog();
                }
                else if (e.Key == Key.F8)
                {
                    Stock st = new Stock(WindowTypes.MainWindowF2);
                    st.Owner = this;
                    st.ShowDialog();
                    CacheManager.ResetCacheManager();
                    ltLessStockDetails.Items.Clear();
                    foreach (BillingGridItemDto itemBG in CacheManager.BillingItems.OrderBy(i => i.Code).ToList())
                    {
                        if (itemBG.IsStockShown)
                            ltLessStockDetails.Items.Add(itemBG);
                    }
                }
                else if (e.Key == Key.F9)
                {
                    DuplicateBill db = new DuplicateBill();
                    db.Owner = this;
                    db.ShowDialog();
                    FocusOnLastItem();
                }
                else if (e.Key == Key.F11)
                {
                    CakeDelivery cb = new CakeDelivery();
                    cb.Owner = this;
                    cb.ShowDialog();
                    FocusOnLastItem();
                }
                else if (e.Key == Key.F12)
                {
                    DeliverBulkOrder deliver = new DeliverBulkOrder();
                    deliver.Owner = this;
                    deliver.ShowDialog();
                    FocusOnLastItem();
                }

                RefreshAllFields();
            }
            catch (Exception) { }
        }

        #endregion

        #region Private Methods

        private void FixRepeatedItems()
        {
            try
            {
                BillingGridItemControl lastItem = ltMainList.Items[ltMainList.Items.Count - 2] as BillingGridItemControl;
                if (lastItem != null)
                {
                    for (int counter = 0; counter < ltMainList.Items.Count - 2; counter++)
                    {
                        if (lastItem.txtCode.Text == (ltMainList.Items[counter] as BillingGridItemControl).txtCode.Text)
                        {
                            BillingGridItemControl ctrl = (ltMainList.Items[counter] as BillingGridItemControl);
                            ctrl.txtQty.Text = (double.Parse(ctrl.txtQty.Text) + double.Parse(lastItem.txtQty.Text)).ToString();
                            ltMainList.Items.Remove(lastItem);
                        }
                    }
                }
            }
            catch (Exception) { }
        }

        private bool IsCodeExist(int p)
        {
            try
            {
                BillingGridItemDto billItem = CacheManager.BillingItems.Find(item => item.Code == p);
                return billItem != null;
            }
            catch (Exception) 
            {
                return false;
            }
        }

        void UpdateBillItemsSlNo()
        {
            try
            {
                int SlNo = 1;
                foreach (BillingGridItemControl itemControl in ltMainList.Items)
                {
                    itemControl.lblSrNo.Content = SlNo++;
                }
            }
            catch (Exception) { }
        }

        BillingGridItemControl GetBillingGridLastItem()
        {
            try
            {
                return (BillingGridItemControl)GetLastItemObjet();
            }
            catch (Exception)
            {
                return null;
            }
        }

        BillingGridItemControl GetCurrentGridItem()
        {
            try
            {
                return (BillingGridItemControl)ltMainList.SelectedItem;
            }
            catch (Exception) { return null; }
        }

        object GetLastItemObjet()
        {
            try
            {
                if (ltMainList.Items.Count > 0)
                    return ltMainList.Items[ltMainList.Items.Count - 1];
                else
                {
                    return new BillingGridItemControl();
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        void FocusOnLastItem()
        {
            try
            {
                ltMainList.SelectedIndex = ltMainList.Items.Count - 1;
            }
            catch (Exception) { }
        }

        void ReadItems()
        {
            try
            {
                CacheManager.LoadItems();
            }
            catch (Exception) { }
        }

        void CancelBill()
        {
            try
            {
                ltMainList.Items.Clear();
                ltMainList.Items.Add(new BillingGridItemControl(this));
                ltMainList.Focus();
                BillingGridItemControl firstItem = (BillingGridItemControl)ltMainList.SelectedItem;
                ltMainList.SelectedIndex = 0;
                UpdateBillItemsSlNo();
            }
            catch (Exception) { }
        }

        void SetDefaults()
        {
            try
            {
                txtPayType.Text = PayTypes.Cash.ToString();
                PaytypeCashAmount = 0;
                PaytypeCardAmount = 0;
                PaytypeSodexoAmount = 0;
                TotalNetAmount = 0;
                TotalAmount = 0;
            }
            catch (Exception) { }
        }

        #endregion

        #region Public Methods

        public void UpdateTotalQty()
        {
            try
            {
                double totalItems = 0;

                foreach (BillingGridItemControl item in ltMainList.Items)
                {
                    try
                    {
                        if (item.txtQty.Text != string.Empty)
                            totalItems += Convert.ToDouble(item.txtQty.Text.Trim());
                    }
                    catch (Exception) { }
                }

                txtQty.Text = totalItems.ToString();
            }
            catch (Exception) { }
        }

        public void UpdateTotalCost()
        {
            try
            {
                Decimal totalCost = 0;

                foreach (BillingGridItemControl item in ltMainList.Items)
                {
                    if (item.txtPrice.Text != string.Empty)
                        totalCost += Convert.ToDecimal(item.txtPrice.Text.Trim());
                }

                TotalAmount = totalCost;
                txtTotal.Text = TotalAmount.ToString();
                txtNetTotal.Text = CalculateNetTotal().ToString();
            }
            catch (Exception) { }
        }

        public void RefreshAllFields()
        {
            try
            {
                UpdateTotalCost();
                UpdateTotalQty();
                UpdateBillItemsSlNo();
                SetPayType(PaytypeCardAmount, PaytypeSodexoAmount);
            }
            catch (Exception) { }
        }

        public decimal CalculateNetTotal()
        {
            try
            {
                DiscountedAmount = ((TotalAmount * DiscountInPercentage) / 100) + DiscountInRs;

                TotalNetAmount = TotalAmount - DiscountedAmount;
                txtDiscount.Text = DiscountInPercentage.ToString() + "% /" + DiscountInRs.ToString() + "Rs.";
                return TotalNetAmount;
            }
            catch (Exception) 
            {
                return 0.0M;
            }
        }

        public void SetPayType(decimal card, decimal sodexo)
        {
            try
            {
                PaytypeCardAmount = card;
                PaytypeSodexoAmount = sodexo;
                PaytypeCashAmount = TotalNetAmount - (PaytypeCardAmount + PaytypeSodexoAmount);

                StringBuilder str = new StringBuilder();

                if (payType.ContainsKey(PayTypes.Cash.ToString())) payType[PayTypes.Cash.ToString()] = PaytypeCashAmount.ToString(); else payType.Add(PayTypes.Cash.ToString(), PaytypeCashAmount.ToString());
                if (payType.ContainsKey(PayTypes.Card.ToString())) payType[PayTypes.Card.ToString()] = PaytypeCardAmount.ToString(); else payType.Add(PayTypes.Card.ToString(), PaytypeCardAmount.ToString());
                if (payType.ContainsKey(PayTypes.Sodexo.ToString())) payType[PayTypes.Sodexo.ToString()] = PaytypeSodexoAmount.ToString(); else payType.Add(PayTypes.Sodexo.ToString(), PaytypeSodexoAmount.ToString());

                if (payType.Keys.Count == 1)
                {
                    str.Append(PayTypes.Cash.ToString() + ":" + PaytypeCashAmount.ToString());
                }
                else
                {
                    foreach (string pay in payType.Keys)
                    {
                        if (payType.Keys.Count > 1 && payType[pay].ToString() != "0")
                        {
                            str.Append("(" + pay + ":" + payType[pay].ToString() + ")");
                        }
                    }
                }
                txtPayType.Text = str.ToString();
            }
            catch (Exception) { }
        }

        #endregion

        #region Properties

        public decimal DiscountedAmount
        {
            get;
            set;
        }

        public decimal TotalAmount
        {
            set;
            get;
        }

        public decimal DiscountInPercentage
        {
            set;
            get;
        }

        public decimal DiscountInRs
        {
            set;
            get;
        }

        public string DiscountReason { get; set; }

        public decimal TotalNetAmount
        {
            set;
            get;
        }

        public decimal PaytypeCashAmount
        {
            get;
            set;
        }

        public decimal PaytypeCardAmount
        {
            get;
            set;
        }

        public decimal PaytypeSodexoAmount
        {
            get;
            set;
        }

        #endregion

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            try
            {
                billingScreensCount = -1;
            }
            catch (Exception) { }
        }
    }
}
